<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */

namespace app\service\fetch\ocean;

use app\enum\CommandEnum;
use app\enum\CommonEnum;
use app\enum\ConfigEnum;
use app\enum\OceanEnum;
use app\model\ClientAccountModel;
use app\model\OeAssetsModel;
use app\model\OeVideoModel;
use app\service\client\AccountService;
use app\service\fetch\MediaInterface;
use app\service\fetch\MediaService;
use app\service\ocean\AdvertiserService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\Model;

class AssetsService extends MediaService implements MediaInterface
{
    /**
     * @var string 数据拉取key
     */
    protected const FETCH_KEY = ConfigEnum::CACHE_CONFIG[OceanEnum::LIST_CONFIG_LOCK_KEY]['assets'];

    /**
     * 拉取巨量推广内容数据列表.
     * @param string $advertiserId 广告主id
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getAssets(string $advertiserId = ''): bool
    {
        $assetType = OceanEnum::APP_ASSET_TYPE; // THIRD_EXTERNAL:三方落地页,APP:应用,QUICK_APP:快应用
        // 获取账户信息
        $obj = AccountService::getAccountModel(0, $advertiserId);
        if (! $obj instanceof ClientAccountModel || ! $obj->getKey()) {
            return self::setError('账户数据不存在');
        }
        foreach ($assetType as $val) {
            $page = 0;
            while (true) {
                $result = self::getList($advertiserId, $val, ++$page);
                if ($result === false) {
                    return false;
                }
                if (empty($result['data']['landing_pages']) && empty($result['data']['quick_app']) && empty($result['data']['app']) && empty($result['data']['mini_program'])) {
                    break;
                }
                $model = self::getInfo($advertiserId, $val);
                if (! $model instanceof OeAssetsModel || ! $model->getKey()) {
                    $model = new OeAssetsModel();
                }
                $model->setAttrs([
                    'advertiser_id' => $advertiserId,
                    'asset_type' => $val,
                    'landing_pages' => json_encode($result['data']['landing_pages']),
                    'quick_app' => json_encode($result['data']['quick_app']),
                    'app' => json_encode($result['data']['app']),
                    'mini_program' => json_encode($result['data']['mini_program']),
                ]);
                if (! $model->save()) {
                    return self::setError('保存信息出错');
                }
            }
        }
        $redis = Cache::store('redis')->handler();
        // 加入修改版本号的状态队列
        $redis->lPush(ConfigEnum::CACHE_CONFIG[OceanEnum::LIST_CONFIG_KEY]['optimized_goal'], $advertiserId);
        $redis->lPush(ConfigEnum::CACHE_CONFIG[OceanEnum::LIST_CONFIG_KEY]['track_url'], $advertiserId);
        return true;
    }

    /**
     * 拉取信息.
     *
     * @param string $advertiserId 账户id
     * @return bool|mixed|string
     */
    private static function getList(string $advertiserId = '', string $assetType = '', int $page = 1)
    {
        $token = AccountService::getToken(CommonEnum::OE_MEDIA, $advertiserId);
        if (! $token) {
            return self::setError('token获取失败');
        }
        $headers = [
            'Access-Token' => $token,
            'Content-Type' => 'application/json',
        ];
        $params = [
            'advertiser_id' => $advertiserId,
            'asset_type' => $assetType,
            'page' => $page,
            'page_size' => 30,
        ];
        return AdvertiserService::getAssets($headers, $params);
    }

    /**
     * 获取视频信息.
     *
     * @param string $advertiserId 账户id
     * @return null|array|mixed|Model|OeVideoModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getInfo(string $advertiserId = '', string $assetType = '')
    {
        $where = [
            ['advertiser_id', '=', $advertiserId],
            ['asset_type', '=', $assetType],
        ];

        return (new OeAssetsModel())->where($where)->field(true)->find();
    }
}
